package dkbta.ontology.elements.context;

import java.util.Collection;
import java.util.List;
import java.util.Set;

import dkbta.ontology.Ontology;
import dkbta.ontology.elements.ElementDef;
import dkbta.ontology.elements.ElementType;
import dkbta.ontology.loading.OntologyException;
import dkbta.processing.ActionTimer;
import dkbta.processing.Patient;

public class ContextDef extends ElementDef{
	/** The sub-contexts of this context */
	private final Set<String> _subContexts;

	/** The inductions for this context */
	private final Collection<Induction> _inductions;

	/**
	 * Initializes a Context with the given name and component type
	 * 
	 * @param name The element's name
	 * @param componentType The element's component type
	 * @param subContexts The sub contexts
	 * @param inductions The inductions from which this context can be generated
	 */
	public ContextDef(String name, String componentType, Set<String> subContexts,
		Collection<Induction> inductions){
		super(ElementType.CONTEXT, name, componentType, null);
		_subContexts = subContexts;
		_inductions = inductions;
	}

	@Override
	public void validate(Ontology ontology) throws OntologyException{
		for (Induction induction : _inductions){
			induction.validate(ontology);
			_prerequisiteElements.add(induction.getRelatedElement(ontology));
		}
		for (String subContext : _subContexts){
			ContextDef subContextDef = ontology.getContext(subContext);
			if (subContextDef == null){
				throw new OntologyException(
						"The context has a non-existing sub-context: " + subContext);
			}
			// TODO Handle sub contexts
			// _prerequisiteElements.add(subContextDef);
		}
	}

	@Override
	public String completeToString(){
		StringBuilder sb = new StringBuilder(super.completeToString());
		sb.append("Sub-contexts: ");
		for (String subContext : _subContexts){
			sb.append("\r\n\t");
			sb.append(subContext);
		}
		sb.append("\r\nInductions: ");
		for (Induction induction : _inductions){
			sb.append("\r\n\t");
			sb.append(induction);
		}
		sb.append("\r\n");
		return sb.toString();
	}

	@Override
	protected void compute(Patient p){
		List<Context> contexts = p.getContexts(_name);

		ActionTimer actionTimer = ActionTimer.getInstance();

		int contextActionId = actionTimer.actionStart();
		for (Induction induction : _inductions){
			induction.computeContexts(p, contexts, _name);
		}
		actionTimer.actionEnd(contextActionId, p.getPatientId(), _name, _type,
			ActionTimer.Action.CONTEXT_GENERATION);
	}

	@Override
	public Context newInstance(long startTime, long endTime, String[] value){
		return new Context(_name, startTime, endTime);
	}

}
